home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.31-14 / kernel / timeconst.pl < prev   
Perl Script  |  2009-09-09  |  7KB  |  379 lines

  1. #!/usr/bin/perl
  2. # -----------------------------------------------------------------------
  3. #
  4. #   Copyright 2007-2008 rPath, Inc. - All Rights Reserved
  5. #
  6. #   This file is part of the Linux kernel, and is made available under
  7. #   the terms of the GNU General Public License version 2 or (at your
  8. #   option) any later version; incorporated herein by reference.
  9. #
  10. # -----------------------------------------------------------------------
  11. #
  12.  
  13. #
  14. # Usage: timeconst.pl HZ > timeconst.h
  15. #
  16.  
  17. # Precomputed values for systems without Math::BigInt
  18. # Generated by:
  19. # timeconst.pl --can 24 32 48 64 100 122 128 200 250 256 300 512 1000 1024 1200
  20. %canned_values = (
  21.     24 => [
  22.         '0xa6aaaaab','0x2aaaaaa',26,
  23.         125,3,
  24.         '0xc49ba5e4','0x1fbe76c8b4',37,
  25.         3,125,
  26.         '0xa2c2aaab','0xaaaa',16,
  27.         125000,3,
  28.         '0xc9539b89','0x7fffbce4217d',47,
  29.         3,125000,
  30.     ], 32 => [
  31.         '0xfa000000','0x6000000',27,
  32.         125,4,
  33.         '0x83126e98','0xfdf3b645a',36,
  34.         4,125,
  35.         '0xf4240000','0x0',17,
  36.         31250,1,
  37.         '0x8637bd06','0x3fff79c842fa',46,
  38.         1,31250,
  39.     ], 48 => [
  40.         '0xa6aaaaab','0x6aaaaaa',27,
  41.         125,6,
  42.         '0xc49ba5e4','0xfdf3b645a',36,
  43.         6,125,
  44.         '0xa2c2aaab','0x15555',17,
  45.         62500,3,
  46.         '0xc9539b89','0x3fffbce4217d',46,
  47.         3,62500,
  48.     ], 64 => [
  49.         '0xfa000000','0xe000000',28,
  50.         125,8,
  51.         '0x83126e98','0x7ef9db22d',35,
  52.         8,125,
  53.         '0xf4240000','0x0',18,
  54.         15625,1,
  55.         '0x8637bd06','0x1fff79c842fa',45,
  56.         1,15625,
  57.     ], 100 => [
  58.         '0xa0000000','0x0',28,
  59.         10,1,
  60.         '0xcccccccd','0x733333333',35,
  61.         1,10,
  62.         '0x9c400000','0x0',18,
  63.         10000,1,
  64.         '0xd1b71759','0x1fff2e48e8a7',45,
  65.         1,10000,
  66.     ], 122 => [
  67.         '0x8325c53f','0xfbcda3a',28,
  68.         500,61,
  69.         '0xf9db22d1','0x7fbe76c8b',35,
  70.         61,500,
  71.         '0x8012e2a0','0x3ef36',18,
  72.         500000,61,
  73.         '0xffda4053','0x1ffffbce4217',45,
  74.         61,500000,
  75.     ], 128 => [
  76.         '0xfa000000','0x1e000000',29,
  77.         125,16,
  78.         '0x83126e98','0x3f7ced916',34,
  79.         16,125,
  80.         '0xf4240000','0x40000',19,
  81.         15625,2,
  82.         '0x8637bd06','0xfffbce4217d',44,
  83.         2,15625,
  84.     ], 200 => [
  85.         '0xa0000000','0x0',29,
  86.         5,1,
  87.         '0xcccccccd','0x333333333',34,
  88.         1,5,
  89.         '0x9c400000','0x0',19,
  90.         5000,1,
  91.         '0xd1b71759','0xfff2e48e8a7',44,
  92.         1,5000,
  93.     ], 250 => [
  94.         '0x80000000','0x0',29,
  95.         4,1,
  96.         '0x80000000','0x180000000',33,
  97.         1,4,
  98.         '0xfa000000','0x0',20,
  99.         4000,1,
  100.         '0x83126e98','0x7ff7ced9168',43,
  101.         1,4000,
  102.     ], 256 => [
  103.         '0xfa000000','0x3e000000',30,
  104.         125,32,
  105.         '0x83126e98','0x1fbe76c8b',33,
  106.         32,125,
  107.         '0xf4240000','0xc0000',20,
  108.         15625,4,
  109.         '0x8637bd06','0x7ffde7210be',43,
  110.         4,15625,
  111.     ], 300 => [
  112.         '0xd5555556','0x2aaaaaaa',30,
  113.         10,3,
  114.         '0x9999999a','0x1cccccccc',33,
  115.         3,10,
  116.         '0xd0555556','0xaaaaa',20,
  117.         10000,3,
  118.         '0x9d495183','0x7ffcb923a29',43,
  119.         3,10000,
  120.     ], 512 => [
  121.         '0xfa000000','0x7e000000',31,
  122.         125,64,
  123.         '0x83126e98','0xfdf3b645',32,
  124.         64,125,
  125.         '0xf4240000','0x1c0000',21,
  126.         15625,8,
  127.         '0x8637bd06','0x3ffef39085f',42,
  128.         8,15625,
  129.     ], 1000 => [
  130.         '0x80000000','0x0',31,
  131.         1,1,
  132.         '0x80000000','0x0',31,
  133.         1,1,
  134.         '0xfa000000','0x0',22,
  135.         1000,1,
  136.         '0x83126e98','0x1ff7ced9168',41,
  137.         1,1000,
  138.     ], 1024 => [
  139.         '0xfa000000','0xfe000000',32,
  140.         125,128,
  141.         '0x83126e98','0x7ef9db22',31,
  142.         128,125,
  143.         '0xf4240000','0x3c0000',22,
  144.         15625,16,
  145.         '0x8637bd06','0x1fff79c842f',41,
  146.         16,15625,
  147.     ], 1200 => [
  148.         '0xd5555556','0xd5555555',32,
  149.         5,6,
  150.         '0x9999999a','0x66666666',31,
  151.         6,5,
  152.         '0xd0555556','0x2aaaaa',22,
  153.         2500,3,
  154.         '0x9d495183','0x1ffcb923a29',41,
  155.         3,2500,
  156.     ]
  157. );
  158.  
  159. $has_bigint = eval 'use Math::BigInt qw(bgcd); 1;';
  160.  
  161. sub bint($)
  162. {
  163.     my($x) = @_;
  164.     return Math::BigInt->new($x);
  165. }
  166.  
  167. #
  168. # Constants for division by reciprocal multiplication.
  169. # (bits, numerator, denominator)
  170. #
  171. sub fmul($$$)
  172. {
  173.     my ($b,$n,$d) = @_;
  174.  
  175.     $n = bint($n);
  176.     $d = bint($d);
  177.  
  178.     return scalar (($n << $b)+$d-bint(1))/$d;
  179. }
  180.  
  181. sub fadj($$$)
  182. {
  183.     my($b,$n,$d) = @_;
  184.  
  185.     $n = bint($n);
  186.     $d = bint($d);
  187.  
  188.     $d = $d/bgcd($n, $d);
  189.     return scalar (($d-bint(1)) << $b)/$d;
  190. }
  191.  
  192. sub fmuls($$$) {
  193.     my($b,$n,$d) = @_;
  194.     my($s,$m);
  195.     my($thres) = bint(1) << ($b-1);
  196.  
  197.     $n = bint($n);
  198.     $d = bint($d);
  199.  
  200.     for ($s = 0; 1; $s++) {
  201.         $m = fmul($s,$n,$d);
  202.         return $s if ($m >= $thres);
  203.     }
  204.     return 0;
  205. }
  206.  
  207. # Generate a hex value if the result fits in 64 bits;
  208. # otherwise skip.
  209. sub bignum_hex($) {
  210.     my($x) = @_;
  211.     my $s = $x->as_hex();
  212.  
  213.     return (length($s) > 18) ? undef : $s;
  214. }
  215.  
  216. # Provides mul, adj, and shr factors for a specific
  217. # (bit, time, hz) combination
  218. sub muladj($$$) {
  219.     my($b, $t, $hz) = @_;
  220.     my $s = fmuls($b, $t, $hz);
  221.     my $m = fmul($s, $t, $hz);
  222.     my $a = fadj($s, $t, $hz);
  223.     return (bignum_hex($m), bignum_hex($a), $s);
  224. }
  225.  
  226. # Provides numerator, denominator values
  227. sub numden($$) {
  228.     my($n, $d) = @_;
  229.     my $g = bgcd($n, $d);
  230.     return ($n/$g, $d/$g);
  231. }
  232.  
  233. # All values for a specific (time, hz) combo
  234. sub conversions($$) {
  235.     my ($t, $hz) = @_;
  236.     my @val = ();
  237.  
  238.     # HZ_TO_xx
  239.     push(@val, muladj(32, $t, $hz));
  240.     push(@val, numden($t, $hz));
  241.  
  242.     # xx_TO_HZ
  243.     push(@val, muladj(32, $hz, $t));
  244.     push(@val, numden($hz, $t));
  245.  
  246.     return @val;
  247. }
  248.  
  249. sub compute_values($) {
  250.     my($hz) = @_;
  251.     my @val = ();
  252.     my $s, $m, $a, $g;
  253.  
  254.     if (!$has_bigint) {
  255.         die "$0: HZ == $hz not canned and ".
  256.             "Math::BigInt not available\n";
  257.     }
  258.  
  259.     # MSEC conversions
  260.     push(@val, conversions(1000, $hz));
  261.  
  262.     # USEC conversions
  263.     push(@val, conversions(1000000, $hz));
  264.  
  265.     return @val;
  266. }
  267.  
  268. sub outputval($$)
  269. {
  270.     my($name, $val) = @_;
  271.     my $csuf;
  272.  
  273.     if (defined($val)) {
  274.         if ($name !~ /SHR/) {
  275.         $val = "U64_C($val)";
  276.         }
  277.         printf "#define %-23s %s\n", $name.$csuf, $val.$csuf;
  278.     }
  279. }
  280.  
  281. sub output($@)
  282. {
  283.     my($hz, @val) = @_;
  284.     my $pfx, $bit, $suf, $s, $m, $a;
  285.  
  286.     print "/* Automatically generated by kernel/timeconst.pl */\n";
  287.     print "/* Conversion constants for HZ == $hz */\n";
  288.     print "\n";
  289.     print "#ifndef KERNEL_TIMECONST_H\n";
  290.     print "#define KERNEL_TIMECONST_H\n";
  291.     print "\n";
  292.  
  293.     print "#include <linux/param.h>\n";
  294.     print "#include <linux/types.h>\n";
  295.  
  296.     print "\n";
  297.     print "#if HZ != $hz\n";
  298.     print "#error \"kernel/timeconst.h has the wrong HZ value!\"\n";
  299.     print "#endif\n";
  300.     print "\n";
  301.  
  302.     foreach $pfx ('HZ_TO_MSEC','MSEC_TO_HZ',
  303.               'HZ_TO_USEC','USEC_TO_HZ') {
  304.         foreach $bit (32) {
  305.             foreach $suf ('MUL', 'ADJ', 'SHR') {
  306.                 outputval("${pfx}_$suf$bit", shift(@val));
  307.             }
  308.         }
  309.         foreach $suf ('NUM', 'DEN') {
  310.             outputval("${pfx}_$suf", shift(@val));
  311.         }
  312.     }
  313.  
  314.     print "\n";
  315.     print "#endif /* KERNEL_TIMECONST_H */\n";
  316. }
  317.  
  318. # Pretty-print Perl values
  319. sub perlvals(@) {
  320.     my $v;
  321.     my @l = ();
  322.  
  323.     foreach $v (@_) {
  324.         if (!defined($v)) {
  325.             push(@l, 'undef');
  326.         } elsif ($v =~ /^0x/) {
  327.             push(@l, "\'".$v."\'");
  328.         } else {
  329.             push(@l, $v.'');
  330.         }
  331.     }
  332.     return join(',', @l);
  333. }
  334.  
  335. ($hz) = @ARGV;
  336.  
  337. # Use this to generate the %canned_values structure
  338. if ($hz eq '--can') {
  339.     shift(@ARGV);
  340.     @hzlist = sort {$a <=> $b} (@ARGV);
  341.  
  342.     print "# Precomputed values for systems without Math::BigInt\n";
  343.     print "# Generated by:\n";
  344.     print "# timeconst.pl --can ", join(' ', @hzlist), "\n";
  345.     print "\%canned_values = (\n";
  346.     my $pf = "\t";
  347.     foreach $hz (@hzlist) {
  348.         my @values = compute_values($hz);
  349.         print "$pf$hz => [\n";
  350.         while (scalar(@values)) {
  351.             my $bit;
  352.             foreach $bit (32) {
  353.                 my $m = shift(@values);
  354.                 my $a = shift(@values);
  355.                 my $s = shift(@values);
  356.                 print "\t\t", perlvals($m,$a,$s), ",\n";
  357.             }
  358.             my $n = shift(@values);
  359.             my $d = shift(@values);
  360.             print "\t\t", perlvals($n,$d), ",\n";
  361.         }
  362.         print "\t]";
  363.         $pf = ', ';
  364.     }
  365.     print "\n);\n";
  366. } else {
  367.     $hz += 0;            # Force to number
  368.     if ($hz < 1) {
  369.         die "Usage: $0 HZ\n";
  370.     }
  371.  
  372.     @val = @{$canned_values{$hz}};
  373.     if (!defined(@val)) {
  374.         @val = compute_values($hz);
  375.     }
  376.     output($hz, @val);
  377. }
  378. exit 0;
  379.